package com.baitiaojun.common.config;

import cn.hutool.core.thread.RejectPolicy;
import com.baitiaojun.common.utils.thread.ThreadsUtils;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;

@Configuration
public class ThreadPoolConfig {

    private static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;

    private static final int QUEUE_CAPACITY = 1000;

    private static final int KEEP_ALIVE = 60;

    /**
     * 自定义线程池
     * @return
     */
    @Bean("threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(CORE_POOL_SIZE * 2);
        executor.setCorePoolSize(CORE_POOL_SIZE);
        executor.setQueueCapacity(QUEUE_CAPACITY);
        executor.setKeepAliveSeconds(KEEP_ALIVE);
        executor.setThreadFactory(new BasicThreadFactory.Builder().build());
        //线程不够了交给主线程同步执行
        executor.setRejectedExecutionHandler(RejectPolicy.CALLER_RUNS.getValue());
        return executor;
    }

    /**
     * 定时线程池,在后台以守护线程执行任务
     * @return
     */
    @Bean("scheduledExecutor")
    public ScheduledExecutorService scheduledExecutorService() {
        return new ScheduledThreadPoolExecutor(CORE_POOL_SIZE,
                new BasicThreadFactory.Builder()
                        .daemon(true)
                        .namingPattern("schedule-pool-%d")
                        .build()) {
            //线程执行任务出现异常则执行此方法
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                ThreadsUtils.printException(r, t); //打印线程异常信息
            }
        };
    }
}
